package com.roy.eureka.server.util;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.roy.eureka.api.anno.OldNodePath;
import com.roy.eureka.api.dto.BaseDto;
import com.roy.eureka.api.message.RequestMessage;

public class MessageUtil {
	private static Logger logger = LoggerFactory.getLogger(MessageUtil.class);

	public static RequestMessage getRequestMessage(BaseDto dto,Class<?> type) {
		try {
			RequestMessage requestMessage = new RequestMessage();
			requestMessage.setBaseName(dto.baseName());
			requestMessage.setSessionName(dto.sessionName());
			requestMessage.setRequestId(UUID.randomUUID().toString());
			requestMessage.setClientId(Thread.currentThread().getName());
			requestMessage.setUserNo(dto.usr_no());
			requestMessage.setMobileNo(dto.mbl_no());

			Map<String, Object> dataArea = new HashMap<String, Object>();
			dataArea.put("BaseName", dto.baseName());
			dataArea.put("SessionName", dto.sessionName());
			//先转换父类声明的属性
			if(null != type.getSuperclass()){
				Field[] paraFields = type.getSuperclass().getDeclaredFields();
				for (Field field : paraFields) {
					OldNodePath anno = field.getAnnotation(OldNodePath.class);
					String getterName = "get" + field.getName().substring(0, 1).toUpperCase()
							+ field.getName().substring(1);
					String nodeVal = type.getSuperclass().getMethod(getterName).invoke(dto).toString();
					if (null != anno && StringUtils.isNotEmpty(anno.value()) && StringUtils.isNotEmpty(nodeVal)) {
						for(String nodePath:anno.value().split(",")){
							String[] keyParts = StringUtils.split(nodePath, ".");
							setData(dataArea,keyParts,0,nodeVal);
						}
					}
				}
			}
			//转换本类声明的属性。这样子类同报文地址的属性可以覆盖父类
			Field[] fields = type.getDeclaredFields();
			for (Field field : fields) {
				OldNodePath anno = field.getAnnotation(OldNodePath.class);
				String getterName = "get" + field.getName().substring(0, 1).toUpperCase()
						+ field.getName().substring(1);
				String nodeVal = type.getMethod(getterName).invoke(dto).toString();
				if (null != anno && StringUtils.isNotEmpty(anno.value()) && StringUtils.isNotEmpty(nodeVal)) {
					for(String nodePath:anno.value().split(",")){
						String[] keyParts = StringUtils.split(nodePath, ".");
						setData(dataArea,keyParts,0,nodeVal);
					}
				}
			}

			requestMessage.setData(dataArea);
			logger.info("参数转换成报文成功 "+requestMessage);
			return requestMessage;
		} catch (Exception e) {
			logger.error("参数转换成报文出错 ",e);
			return null;
		}
	}
	
	private static void setData(Map<String, Object> dataArea, String[] keyParts, int idx, String value) {
        if (keyParts.length == (idx + 1)) {
            dataArea.put(keyParts[idx], value);
            return;
        }
        String key = keyParts[idx];
        if (dataArea.get(key) == null) {
            dataArea.put(key, new HashMap<String, Object>());
        }
        setData((Map<String, Object>) dataArea.get(key), keyParts, idx + 1, value);
    }
}
